#include "stdafx.h"
using namespace std;

Mod_Snow::Mod_Snow(Mod_in *iinp):Mod_out_handling(iinp)
{
;}
Mod_Snow::~Mod_Snow()
{;}
int Mod_Snow::compute(time_intervall &ti){}
 double Compute_Snow_growth::compute(const Inp_weather *weather, const time_intervall &ti)const
 {
	 double T=weather->get_rate("T",ti);
	 double P=weather->get_rate("P",ti);
	 double S_increase;
	 int decis= (T<=0)*2+((T>0)&&(T<0.5))*1;//Temperaturbereich, wo's schneien k�nnte
		switch (decis)
		{
			case(1):S_increase=P*0.5;
			break;
			case(2):S_increase=P;
			break;
			case(0): S_increase=0;
			break;
		}
		return S_increase;
 }
 double Compute_Snow_melt_Tagesgradverfahren::compute(const Mod_in *iinp,const Inp_weather *weather,const time_intervall &ti){
	   double T=weather->get_rate("T",ti);
	   return Basics_math::max_((double)0,(double)T*2);
 }
 
 Mod_Snow_simple::~Mod_Snow_simple(){;}
 Mod_Snow_simple::Mod_Snow_simple(map<string,int>& iIO_options, 
         Mod_in* iinp, Inp_weather* iweather, 
         Compute_Snow_melt* isnow_melt, 
         Mod_ETP* imod_etp, 
         Compute_Snow_growth* isnow_growth):Mod_Snow(iinp)
         
                        
 {
     IO_options=iIO_options;
    
     inp_weather= iweather;
     snow_melt=isnow_melt;
     mod_etp=imod_etp;
     snow_growth=isnow_growth;
     
     
    
     
     // Output Kategorien setzen
     out->fluxes.set_key((string)"Snow_growth");
     out->fluxes.set_key("Snow_melt");
     out->fluxes.set_key("Snow_ETR");
     timepointmap <double> null_timepointmap(iinp->tempgrid);
    
     //out->states.insert(pair <"Snow_depth",null_timepointmap>);
     out->states["Snow_depth"]=null_timepointmap;
     out->states["Snow_equivalent"]=null_timepointmap;
     
     
     
 }

 int Mod_Snow_simple::compute(time_intervall& ti){
     // die Änderung der Schneedecke ergibt sich aus:
     //SH(t)=SH(t-1)+snow_increase
     //SH(t)=max(0;SH(t)-snowmelt)
     //SH(t)=max(0;SH(t)-snowmelt)
     string test2="Snow_depth";
     timestamp end=ti.get_end();
     timestamp start=ti.get_start();
     double SH = this->get_states("Snow_equivalent",start); 
     double SM;
     double snow_ETR;
     double SG=this->snow_growth->compute(inp_weather,ti);
     
     SH=SH+SG;
     SM=min(SH,this->snow_melt->compute(inp,inp_weather,ti));
     SH=SH-SM;
     string test ="ETP_Snowevaporation";
     snow_ETR= min(SH,this->mod_etp->get_fluxes("ETP_Snowevaporation",ti));
     SH=SH-snow_ETR;
     
     this->set_push_back_fluxes("Snow_growth",ti,SG);
     this->set_push_back_fluxes("Snow_melt",ti,SM);
     this->set_push_back_fluxes("Snow_ETR",ti,snow_ETR);
     this->set_states((string)"Snow_depth",end,SH*10);
     this->set_states((string)"Snow_equivalent",end,SH);
     return 0;
 }

//double Mod_Snow::get_snow_height (timestamp &ts)
//{
//	 //returns snowheight in mm per time intervall 
//	double snowcov;
//	double intersectdur;
//	double dur;
//	unsigned int row;
//	map <string,double> resultstore;
//		
//	// case read from file
//	if(inp->IO_options["READ_FROM_FILE"])
//	{
//		row=this->snowcover->get_row(ts);
//		if(row<this->snowcover->get_size())
//		{
//			snowcov=this->snowcover->get_val(row);
//			return snowcov;
//		}
//	}
//        //case the values are however already there
//        if (this->snowcover->get_val(ts)!=this->snowcover->nodata)
//        {
//            return this->snowcover->get_val(ts);
//        }
//        //values have to be calculated
//      
//	
//	// wenn jetz noch h�here Zeiten insnowcover sind, dann sollten diese gel�scht werden
//	if(snowcover_start==this->snowcover->get_size()){
//		err::err3("mod_Snow::get_snow_height: there is now initial value in snowcover");
//        }
//	if(snowcover_start<(this->snowcover->get_size()-1)) {
//		snowcover->set_delete_entries(snowcover_start+1,snowcover->get_size()-1);
//	}	
//        
//	timestamp start_time=this->snowcover->get_timestamp(snowcover_start);
//	
//	unsigned int first=inp->tempgrid->get_pos_of_corresponding_time_intervall(start_time);
//	if (first==inp->tempgrid->get_size()){
//		err::err3("mod_Snow::get_snow_height: last date of snowcover not within tempgrid");
//	}
//	unsigned int last=inp->tempgrid->get_pos_where_ts_bigger_than_this_start(ts);
//	if	(last==this->inp->tempgrid->get_size()){
//		err::err3("modSnow::getSnow_height:ts not completly covered by tempgrid");
//		return 1;
//	}
//		
//	final_time=this->inp->tempgrid->get_time_intervall()
//	// loop starts now with firstvalue and ends with last value
//	tempmap_loop loop(inp->tempgrid,start_time,ts);
//
//	do
//	{
//		
//	}
//	while	(loop.criterion()==0);
//	for(row=first;row<=last;row++)
//	{
//		intersectdur= inp->tempgrid->get_time_intervall(row).get_dur_by_intersect(ti);
//		dur=inp->tempgrid->get_time_intervall(row).get_dur();
//		if(inp->IO_options["READ_FROM_FILE"]){
//			
//		}
//		else{
//			snocov=etpsum+calc_method->calc(inp,row)*intersectdur/dur;
//			resultstore["ETP"]=calc_method->calc(inp,row);
//			if(inp->IO_options["STORE_VALUES"]) this->out->set_insert_or_replace_entry(inp->tempgrid->get_time_intervall(row),resultstore);
//		}
//	}	
//	return etpsum;
//}

Compute_Snow_melt::Compute_Snow_melt(){;}
Compute_Snow_melt::~Compute_Snow_melt(){;}
Compute_Snow_melt_Tagesgradverfahren::Compute_Snow_melt_Tagesgradverfahren():Compute_Snow_melt()
{;}
Compute_Snow_melt_Tagesgradverfahren::~Compute_Snow_melt_Tagesgradverfahren(){;}